<template>
  <div class="ui-map" :style="style">
    <div ref="control" class="ui-map__control" />
    <div v-if="loading" class="ui-map__loading">
      <ui-loading :visible="true"></ui-loading>
    </div>
    <template v-if="ready">
      <slot></slot>
    </template>
  </div>
</template>
<script>
import { loadMapScript } from './utils'
import UiLoading from '../loading'

export default {
  name: 'UiMap',
  components: {
    UiLoading
  },
  provide() {
    return {
      UiMap: this
    }
  },
  props: {
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    zoom: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      ready: false,
      loading: false
    }
  },
  computed: {
    style() {
      return {
        width: this.width,
        height: this.height
      }
    }
  },
  mounted() {
    this.init().then(() => {
      this.autoPosition()
      this.ready = true
      this.map.on('click', this.handleMapClick)
    })
  },
  methods: {
    init() {
      this.loading = true
      return loadMapScript().then(AMap => {
        this.AMap = AMap
        this.map = new AMap.Map(this.$refs.control, {
          zoom: this.zoom
        })
      }).finally(() => {
        this.loading = false
      })
    },
    /**
     * 自动定位
    */
    autoPosition() {
      return new Promise((resolve, reject) => {
        loadMapScript().then(AMap => {
          AMap.plugin('AMap.Geolocation', () => {
            const geolocation = new AMap.Geolocation({
              enableHighAccuracy: true, // 是否使用高精度定位，默认:true
              timeout: 10000, // 超过10秒后停止定位，默认：5s
              position: 'RB', // 定位按钮的停靠位置
              offset: [10, 20], // 定位按钮与设置的停靠位置的偏移量，默认：[10, 20]
              zoomToAccuracy: true // 定位成功后是否自动调整地图视野到定位点
            })
            this.map.addControl(geolocation)
            geolocation.getCurrentPosition((status, result) => {
              if (status === 'complete') {
                resolve(result)
              } else {
                reject(result)
              }
            })
          })
        }, reject)
      })
    },
    getAddressByLnglat(lnglat) {
      return new Promise((resolve, reject) => {
        loadMapScript().then(AMap => {
          AMap.plugin('AMap.Geocoder', function() {
            var geocoder = new AMap.Geocoder()
            geocoder.getAddress(lnglat, (status, result) => {
              if (status === 'complete' && result.info === 'OK') {
                // result为对应的地理位置详细信息
                resolve(result)
              } else {
                reject(result)
              }
            })
          })
        })
      })
    },
    getLnglatByAddress(address) {
      return new Promise((resolve, reject) => {
        loadMapScript().then(AMap => {
          AMap.plugin('AMap.Geocoder', function() {
            var geocoder = new AMap.Geocoder()
            geocoder.getLocation(address, function(status, result) {
              if (status === 'complete' && result.info === 'OK') {
                if (!result.geocodes || !result.geocodes.length) {
                  reject()
                } else {
                  resolve({
                    lat: result.geocodes[0].location.lat,
                    lng: result.geocodes[0].location.lng
                  })
                }
              } else {
                reject(result)
              }
            })
          })
        }, reject)
      })
    },
    setCenter(lnglat) {
      if (!this.map) {
        return
      }
      this.map.setCenter(lnglat)
    },
    handleMapClick(evt) {
      const lng = evt.lnglat.getLng()
      const lat = evt.lnglat.getLat()
      this.getAddressByLnglat([lng, lat]).then((rs) => {
        this.$emit('click', {
          lng,
          lat,
          address: rs.regeocode.formattedAddress
        })
      })
    }
  },
  beforeDestroy() {
    if (this.map) {
      this.map.destroy()
    }
  }
}
</script>
<style lang="less">
.ui-map {
  position: relative;
}
.ui-map__control{
  width: 100%;
  height: 100%;
}
.ui-map__loading{
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
}
</style>
